package com.myscreen.server;

import com.myscreen.ui.ClientScreenPanel;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

public class ScreenMonitorServer extends JFrame implements ActionListener, TreeSelectionListener {

    private JTree clientTree;
    private DefaultMutableTreeNode rootNode;
    private JTabbedPane tabbedPane;
    private Map<String, ClientHandler> clientHandlers = new HashMap<>();
    private ServerSocket serverSocket;
    private ExecutorService executorService = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("Usage: java ScreenMonitorClient <serverHost> <serverPort>");
            System.exit(1);
        }

        int serverPort = Integer.parseInt(args[0]);
        new ScreenMonitorServer(serverPort);
    }

    public ScreenMonitorServer(int port) {
        super("Screen Monitor Server");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 600);

        // 设置布局  
        JPanel contentPane = new JPanel(new BorderLayout());
        clientTree = new JTree();
        rootNode = new DefaultMutableTreeNode("Clients");
        clientTree.setModel(new DefaultTreeModel(rootNode));
        clientTree.addTreeSelectionListener(this);

        tabbedPane = new JTabbedPane();

        contentPane.add(new JScrollPane(clientTree), BorderLayout.WEST);
        contentPane.add(tabbedPane, BorderLayout.CENTER);

        setContentPane(contentPane);
        setVisible(true);

        // 启动服务器线程来监听客户端连接  
        startServer(port);
    }

    private void startServer(int port) {
        new Thread(() -> {
            try {
                serverSocket = new ServerSocket(port);
                while (true) {
                    Socket socket = serverSocket.accept();
                    String clientName = "Client_" + socket.getInetAddress().getHostAddress() + "_" + socket.getPort();
                    DefaultMutableTreeNode clientNode = new DefaultMutableTreeNode(clientName);
                    rootNode.add(clientNode);
                    ((DefaultTreeModel) clientTree.getModel()).reload(rootNode);
                    int index = clientHandlers.size();
                    ClientHandler handler = new ClientHandler(socket, clientName, tabbedPane, index);
                    clientHandlers.put(clientName, handler);
                    executorService.submit(handler);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    @Override
    public void valueChanged(TreeSelectionEvent e) {
        // 可以在这里添加选择客户端时的逻辑，比如显示选中客户端的详细信息  
    }

    @Override
    public void actionPerformed(ActionEvent e) {

    }

    // 客户端处理器类  
    private class ClientHandler implements Runnable {
        private Socket socket;
        private String clientName;
        private JTabbedPane tabbedPane;
        private ClientScreenPanel panel;
        int index;

        public ClientHandler(Socket socket, String clientName, JTabbedPane tabbedPane, int index) {
            this.socket = socket;
            this.clientName = clientName;
            this.tabbedPane = tabbedPane;
            this.index = index;
            panel = new ClientScreenPanel();
            tabbedPane.add(clientName, panel);
        }

        @Override
        public void run() {

            AtomicBoolean outer = new AtomicBoolean(false);
            while (true) {
//                SwingUtilities.invokeLater(() -> {
                try {
                    /*ClientScreenPanel panel = new ClientScreenPanel();
                    int i = -1;
                    if (null != panel0) {
                        i = tabbedPane.indexOfComponent(panel0);
                        if (i >= 0) {
                            tabbedPane.remove(i);
                        }
                    }
                    panel0 = panel;
                    tabbedPane.add(panel, i < 0 ? 0 : i);
                    panel.setName(clientName);*/
                    panel.updateImage(socket);
                } catch (IOException e) {
                    if (!socket.isClosed()) {
                        // 不是由于socket已关闭导致的异常，可能是真正的IO问题
                        e.printStackTrace();
                    } else {
                        // 客户端正常断开连接
                        System.out.println("Client disconnected gracefully.");
                    }
                    clientHandlers.remove(clientName);
                    outer.set(true);
                } catch (InterruptedException e) {
                    // 线程被中断时，可以优雅地退出循环
                    System.out.println("Client handler thread interrupted.");
                    Thread.currentThread().interrupt(); // 重置中断状态
                    clientHandlers.remove(clientName);
                    outer.set(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
//                });

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (outer.get()) {
                    break;
                }
            }
        }
    }
}